<template>
	<div>
		<div class="z-whiteboard">
			<div id="canvasDiv" class="canvasDiv">
				<canvas id="handWhiteboard" width="300" height="300" style=""></canvas>
				<div class="code">AS894DJKlILJK00UUIHUIU98</div>
			</div>
			<div class="op">
				<div class="btn1" @click="clearCanvas()">清除</div>
				<div class="btn2" @click="saveImageInfo()">确定</div>
			</div>
		</div>
	</div>
</template>
<script>
import { uploadBase64Image } from '../tool/uploadFile';
export default {
	name: 'WhiteBoard',
	data() {
		return {
			drawType: null,
			whiteboardCanvas: null,
			chache: null,
			textbox: null,
			drawingObject: null,
			mouseFrom: {},
			mouseTo: {},
			doDrawing: false,
			moveCount: 1,
			drawWidth: 3,
			color: '#E34F51',
			colorset: false,
			zoom: window.zoom ? window.zoom : 1
		};
	},
	props: {
		responseHandWriting: {
			type: Function,
			default: null
		},
		cmdId: {
			type: Number,
			default: () => 0
		},
		clientId: {
			type: String,
			default: () => ''
		}
	},
	mounted() {
		this.$nextTick(() => {
			//访客同意签名
			this.responseHandWriting(
				this.cmdId,
				'accepted',
				undefined,
				this.clientId,
				res => {
					console.log(res, 'response accepted hand writing success');
				},
				err => {
					this.$Message.error(this.$t('ivcs.sendfailed'));
					console.log(err);
				}
			);
		});
		var self = this;
		// eslint-disable-next-line no-undef
		this.whiteboardCanvas = new fabric.Canvas('handWhiteboard');
		this.whiteboardCanvas.isDrawingMode = true;
		this.whiteboardCanvas.freeDrawingBrush.color = this.color;
		this.whiteboardCanvas.on('mouse:down', function(options) {
			var xy = self.transformMouse(options.e.offsetX, options.e.offsetY);
			self.mouseFrom.x = xy.x;
			self.mouseFrom.y = xy.y;
			self.doDrawing = true;
		});
		this.whiteboardCanvas.on({
			'mouse:up': options => {
				var xy = self.transformMouse(options.e.offsetX, options.e.offsetY);
				self.mouseTo.x = xy.x;
				self.mouseTo.y = xy.y;
				self.drawingObject = null;
				self.moveCount = 1;
				self.doDrawing = false;
				self.updateCanvas();
			}
		});

		this.whiteboardCanvas.on('selection:created', function(e) {
			if (e.target._objects) {
				//多选删除
				var etCount = e.target._objects.length;
				for (var etindex = 0; etindex < etCount; etindex++) {
					self.whiteboardCanvas.remove(e.target._objects[etindex]);
				}
			} else {
				//单选删除
				self.whiteboardCanvas.remove(e.target);
			}
			self.whiteboardCanvas.discardActiveObject(); //清楚选中框
		});

		this.whiteboardCanvas.on('mouse:move', function(options) {
			if (self.moveCount % 2 && !self.doDrawing) {
				//减少绘制频率
				return;
			}
			self.moveCount++;
			var xy = self.transformMouse(options.e.offsetX, options.e.offsetY);
			self.mouseTo.x = xy.x;
			self.mouseTo.y = xy.y;
			self.drawing();
		});
	},
	methods: {
		async saveImageInfo() {
			var c = document.getElementById('handWhiteboard');
			var image = c.toDataURL('image/png');
			let data = await this.sendbase64img(image);
			if (data) {
				let msgData = {
					url: data.url,
					type: 'pic',
					name: data.name
				};
				/** 访客签名成功 */
				this.responseHandWriting(
					this.cmdId,
					'done',
					msgData,
					this.clientId,
					res => {
						console.log(res, 'hand writing success');
					},
					err => {
						this.$Message.error(this.$t('ivcs.sendfailed'));
						console.log(err);
					}
				);
			}
			this.$emit('sxqmcode');
		},
		/*发送base64的image*/
		sendbase64img(image) {
			let data = uploadBase64Image(image);
			if (data) {
				return data;
			} else {
				this.$Message.error(this.$t('ivcs.sendfailed'));
				return null;
			}
		},

		drawing() {
			/* eslint-disable */
			if (this.drawingObject) {
				this.whiteboardCanvas.remove(this.drawingObject);
			}
			var canvasObject = null;
			switch (this.drawType) {
				case 'arrow': //箭头
					canvasObject = new fabric.Path(this.drawArrow(this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y, 30, 30), {
						stroke: this.color,
						fill: 'rgba(255,255,255,0)',
						strokeWidth: this.drawWidth
					});
					break;
				case 'line': //直线
					canvasObject = new fabric.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y], {
						stroke: this.color,
						strokeWidth: this.drawWidth
					});
					break;
				case 'dottedline': //虚线
					canvasObject = new fabric.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y], {
						strokeDashArray: [3, 1],
						stroke: this.color,
						strokeWidth: this.drawWidth
					});
					break;
				case 'circle': //正圆
					var left = this.mouseFrom.x,
						top = this.mouseFrom.y;
					var radius = Math.sqrt((this.mouseTo.x - left) * (this.mouseTo.x - left) + (this.mouseTo.y - top) * (this.mouseTo.y - top)) / 2;
					canvasObject = new fabric.Circle({
						left: left,
						top: top,
						stroke: this.color,
						fill: 'rgba(255, 255, 255, 0)',
						radius: radius,
						strokeWidth: this.drawWidth
					});
					break;
				case 'ellipse': //椭圆
					var left = this.mouseFrom.x,
						top = this.mouseFrom.y;
					var radius = Math.sqrt((this.mouseTo.x - left) * (this.mouseTo.x - left) + (this.mouseTo.y - top) * (this.mouseTo.y - top)) / 2;
					canvasObject = new fabric.Ellipse({
						left: left,
						top: top,
						stroke: this.color,
						fill: 'rgba(255, 255, 255, 0)',
						originX: 'center',
						originY: 'center',
						rx: Math.abs(left - this.mouseTo.x),
						ry: Math.abs(top - this.mouseTo.y),
						strokeWidth: this.drawWidth
					});
					break;
				case 'square': //TODO:正方形（后期完善）
					break;
				case 'rectangle': //长方形
					var path = 'M ' + this.mouseFrom.x + ' ' + this.mouseFrom.y + ' L ' + this.mouseTo.x + ' ' + this.mouseFrom.y + ' L ' + this.mouseTo.x + ' ' + this.mouseTo.y + ' L ' + this.mouseFrom.x + ' ' + this.mouseTo.y + ' L ' + this.mouseFrom.x + ' ' + this.mouseFrom.y + ' z';
					canvasObject = new fabric.Path(path, {
						left: left,
						top: top,
						stroke: this.color,
						strokeWidth: this.drawWidth,
						fill: 'rgba(255, 255, 255, 0)'
					});
					//也可以使用fabric.Rect
					break;
				case 'rightangle': //直角三角形
					var path = 'M ' + this.mouseFrom.x + ' ' + this.mouseFrom.y + ' L ' + this.mouseFrom.x + ' ' + this.mouseTo.y + ' L ' + this.mouseTo.x + ' ' + this.mouseTo.y + ' z';
					canvasObject = new fabric.Path(path, {
						left: left,
						top: top,
						stroke: this.color,
						strokeWidth: this.drawWidth,
						fill: 'rgba(255, 255, 255, 0)'
					});
					break;
				case 'equilateral': //等边三角形
					var height = this.mouseTo.y - this.mouseFrom.y;
					canvasObject = new fabric.Triangle({
						top: this.mouseFrom.y,
						left: this.mouseFrom.x,
						width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2.0, 2)),
						height: height,
						stroke: this.color,
						strokeWidth: this.drawWidth,
						fill: 'rgba(255,255,255,0)'
					});
					break;
				case 'isosceles':
					break;
				case 'text':
					var textbox = new fabric.Textbox('', {
						left: this.mouseFrom.x,
						top: this.mouseFrom.y,
						width: 150,
						fontSize: 18,
						borderColor: '#2c2c2c',
						fill: this.color,
						hasControls: false
					});
					this.textbox = textbox;
					this.whiteboardCanvas.add(this.textbox);
					this.textbox.enterEditing();
					this.textbox.hiddenTextarea.focus();
					console.log(this.textbox);
					break;
				case 'remove':
					break;
				default:
					break;
			}
			if (canvasObject) {
				// canvasObject.index = getCanvasObjectIndex();
				this.whiteboardCanvas.add(canvasObject); //.setActiveObject(canvasObject)
				this.drawingObject = canvasObject;
			}
			/* eslint-enable */
		},
		drawArrow(fromX, fromY, toX, toY, theta, headlen) {
			// 绘制箭头
			theta = typeof theta != 'undefined' ? theta : 30;
			headlen = typeof theta != 'undefined' ? headlen : 10;
			// 计算各角度和对应的P2,P3坐标
			var angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,
				angle1 = ((angle + theta) * Math.PI) / 180,
				angle2 = ((angle - theta) * Math.PI) / 180,
				topX = headlen * Math.cos(angle1),
				topY = headlen * Math.sin(angle1),
				botX = headlen * Math.cos(angle2),
				botY = headlen * Math.sin(angle2);
			var arrowX = fromX - topX,
				arrowY = fromY - topY;
			var path = ' M ' + fromX + ' ' + fromY;
			path += ' L ' + toX + ' ' + toY;
			arrowX = toX + topX;
			arrowY = toY + topY;
			path += ' M ' + arrowX + ' ' + arrowY;
			path += ' L ' + toX + ' ' + toY;
			arrowX = toX + botX;
			arrowY = toY + botY;
			path += ' L ' + arrowX + ' ' + arrowY;
			return path;
		},
		transformMouse(mouseX, mouseY) {
			return { x: mouseX / this.zoom, y: mouseY / this.zoom };
		},
		showCache(data) {
			this.whiteboardCanvas.loadFromJSON(JSON.parse(data || this.chache));
			this.whiteboardCanvas.renderAll();
		},
		updateCanvas() {
			var canvasStringify = JSON.stringify(this.whiteboardCanvas);
			this.chache = canvasStringify;
			console.log(this.chache);
			this.sedMessage();
		},
		clearCanvas() {
			this.whiteboardCanvas.clear();
			this.updateCanvas();
		},
		//访客正在签名  data:签名轨迹
		sedMessage() {
			var code = this.chache;
			let data = { stroke: code };
			this.responseHandWriting(
				this.cmdId,
				'in-progress',
				data,
				this.clientId,
				res => {
					console.log(res, 'hand writing in-progress success');
				},
				err => {
					this.$Message.error(this.$t('ivcs.sendfailed'));
					console.log(err);
				}
			);
		}
	}
};
</script>

<style scoped>
.z-whiteboard {
	z-index: 100;
	position: absolute;
	background-color: #fff;
	width: 90%;
	margin: 0 5%;
	transform: translateY(-50%);
	top: 50%;
}

.btn1 {
	width: 80px;
	height: 40px;
	border-radius: 4px;
	margin-right: 30px;
	background: rgba(0, 194, 255, 1);
	border: 0px solid rgba(102, 102, 102, 1);
	color: white;
	font-size: 14px;
	line-height: 40px;
}
.btn2 {
	width: 80px;
	height: 40px;
	background: rgba(0, 194, 255, 1);
	border-radius: 4px;
	color: white;
	font-size: 14px;
	border: 0px;
	line-height: 40px;
}

.op {
	padding-bottom: 4%;
	height: 50px;
	display: flex;
	flex-direction: row;
	justify-content: center;
	align-items: center;
}

.canvasDiv {
	position: relative;
	width: 300px;
	height: 330px;
	border: 1px solid #cecece;
	margin: 10% auto;
}

.code {
	position: absolute;
	left: 0px;
	height: 30px;
	bottom: 0px;
}
</style>
